package net.mikoo.seals.biz.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;

import net.mikoo.seals.biz.common.BaseServices;
import net.mikoo.seals.biz.mapper.DevicesMapper;
import net.mikoo.seals.biz.mapper.InstallMapper;
import net.mikoo.seals.biz.mapper.PersonMapper;
import net.mikoo.seals.biz.mapper.StaffMapper;
import net.mikoo.seals.biz.service.InstallServices;
import net.mikoo.seals.common.enums.DevicesStatusEnum;
import net.mikoo.seals.common.enums.InstallStatusEnum;
import net.mikoo.seals.common.enums.InstallTypeEnum;
import net.mikoo.seals.common.enums.StaffTypeEnum;
import net.mikoo.seals.common.exception.ParametersException;
import net.mikoo.seals.common.model.PageModel;
import net.mikoo.seals.model.Devices;
import net.mikoo.seals.model.Install;
import net.mikoo.seals.model.InstallQuery;
import net.mikoo.seals.model.Person;
import net.mikoo.seals.model.Staff;
import net.mikoo.seals.model.StaffQuery;



@Service
public class InstallServicesImpl extends BaseServices implements InstallServices {
	
	Logger logger = LoggerFactory.getLogger(InstallServicesImpl.class);

	@Autowired
	private InstallMapper installMapper;
	
	@Autowired
	private StaffMapper staffMapper;
	
	@Autowired
	private DevicesMapper devicesMapper;
	
	@Autowired
	private PersonMapper personMapper;
	
	@Override
	public Install getInfoById(Long InstallId) {
		
		if(InstallId == null){
			throw new ParametersException("InstallId is null!");
		}
		
		Install install = installMapper.selectInfoById(InstallId);
		
		if(install != null) {
			Devices devices = devicesMapper.selectInfoById(install.getDevicesId());
			if(devices != null) {
				install.setDevices(devices);
			}
			
			Person person = personMapper.selectByPartyId(install.getPartyId());
			if(person != null) {
				install.setPerson(person);
			}
		}
		
		return install;
	}
	
	
	
	@Override
	public PageModel<Install> getPageByQuery(InstallQuery query) {
		
		List<Install> datas = installMapper.selectPageByQuery(query);
		Integer total = installMapper.countPageByQuery(query);
		PageModel<Install> pm = new PageModel<Install>(total,datas);
		return pm;
	}

	@Override
	public void apply(Install install) {
		if(install == null) {
			throw new ParametersException("install is null");
		}
		
		if(install.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		
		if(install.getDevicesId() == null) {
			throw new ParametersException("DevicesId is null");
		}
		
		if(install.getPartyId() == null) {
			throw new ParametersException("申请人不能为空");
		}
		
		if(StringUtils.isBlank(install.getInstallType())) {
			throw new ParametersException("安装类型不能为空");
		}
		
		if(InstallTypeEnum.getByCode(install.getInstallType()) ==null) {
			throw new ParametersException("安装类型输入有误");
		}
		
		Devices devices = devicesMapper.selectInfoById(install.getDevicesId());
		if(devices == null || (
				!DevicesStatusEnum.WAIT_INSTALL.getCode().equals(devices.getDevicesStatus()) && 
				!DevicesStatusEnum.ACTIVATE.getCode().equals(devices.getDevicesStatus())
				)) {
			throw new IllegalStateException("印章不是带安装或已激活状态");
		}
		
		//获取法人
		StaffQuery query = new StaffQuery();
		query.setStaffType(StaffTypeEnum.LEGAL_PERSON.code());
		query.setCompanyId(install.getCompanyId());
		
		Staff staff = staffMapper.selectInfoByQuery(query);
		
		install.setSealId(devices.getSealId());
		install.setApplyTime(new Date());
		install.setInstallStatus(InstallStatusEnum.PENDING.code());
		install.setVerifyPartyId(staff.getPartyId());
		devices.setDevicesStatus(DevicesStatusEnum.INSTALL_APPLY.getCode());
		
		this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {

			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				installMapper.insert(install);
				devicesMapper.update(devices);
			}
		});
	}



	@Override
	public void verify(Install install) {
		
		if(install == null) {
			throw new ParametersException("install is null");
		}
		
		if(install.getInstallId() == null) {
			throw new ParametersException("InstallId is null");
		}
		
		if(install.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		Install existInstall = installMapper.selectInfoByQuery(new InstallQuery(install.getCompanyId(),install.getInstallId()));
		
		if(existInstall == null) {
			throw new ParametersException("安装申请不存在");
		}
		if(!install.getVerifyPartyId().equals(existInstall.getVerifyPartyId())) {
			throw new ParametersException("您无权操作审核");
		}
		
		if(!existInstall.getInstallStatus().equals(InstallStatusEnum.PENDING.code())) {
			throw new ParametersException("安装申请状态不处于待审核状态");
		}
		
		Devices devices = devicesMapper.selectInfoById(existInstall.getDevicesId());
		if(devices == null) {
			throw new ParametersException("设备不存在");
		}
		
		if(!devices.getDevicesStatus().equals(DevicesStatusEnum.INSTALL_APPLY.code())) {
			throw new ParametersException("当前设置不处于安装待审核状态");
		}
		
		this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				
				
				try {
					existInstall.setInstallStatus(install.getInstallStatus());
					existInstall.setVerifyTime(new Date());
					installMapper.update(existInstall);
					
					if(install.getInstallStatus().equals(InstallStatusEnum.PASSED.code())) {
						if(InstallTypeEnum.INIT.getCode().equals(existInstall.getInstallType())) {
							devices.setDevicesStatus(DevicesStatusEnum.INSTALL_VERIFY.code());
						}else {
							devices.setDevicesStatus(DevicesStatusEnum.RESET_INSTALL_VERIFY.code());
						}
					}else {
						if(InstallTypeEnum.INIT.getCode().equals(existInstall.getInstallType())) {
							devices.setDevicesStatus(DevicesStatusEnum.WAIT_INSTALL.code());
						}else {
							devices.setDevicesStatus(DevicesStatusEnum.ACTIVATE.code());
						}
					}
					devicesMapper.update(devices);
					//发送模板提醒
					
				}catch (Exception e) {
					logger.error("",e);
					status.setRollbackOnly();
					throw e;
				}
			}
		});
	}



	@Override
	public void save(Install install) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void modify(Install install) {
		// TODO Auto-generated method stub
		
	}

	
}
